Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#include <avr/pgmspace.h>
- #include <avr/interrupt.h>
- #include <util/atomic.h>
- #include <util/delay.h>
- #include <avr/wdt.h>
- #include <avr/io.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "io.h"
- #include "uart.h"
- #include "task.h"
- #include "1wire.h"
- #include "ds18b20.h"
- #define FAN B,1
- #define LED_R B,2
- #define LED_G B,3
- #define LED_B B,4
- #define LED_W B,5
- #define DS_IN C,1
- //#define streq(a,b) (strncmp(a,b,sizeof(b)-1)==0)
- #define streq(a,b) (strncmp(a,b,strlen(b))==0)
- #define F_PWM 100
- #define PWM_STEPS 255
- #define PWM_PORT PORTB
- static volatile uint8_t pwm_setting[4];
- static volatile uint8_t ready_to_get_temp=0;
- ISR(TIMER2_OVF_vect) {
- static uint8_t pwm_cnt=0;
- uint8_t tmp=0;
- if (pwm_setting[0] > pwm_cnt) tmp |= (1<<2); //R
- if (pwm_setting[1] > pwm_cnt) tmp |= (1<<3); //G
- if (pwm_setting[2] > pwm_cnt) tmp |= (1<<4); //B
- if (pwm_setting[3] > pwm_cnt) tmp |= (1<<5); //W
- PWM_PORT = tmp;
- if (pwm_cnt==(uint8_t)(PWM_STEPS-1))
- pwm_cnt=0;
- else
- pwm_cnt++;
- }
- uint8_t atoia(char *src, uint8_t *dst, int len){
- // This function convert char array with digits into ints array.
- // In addition return amount of digits that was able to find in *src.
- // If more digits is in *src then max size of *dst, then zero is returned and
- // *dst is zeroed.
- uint8_t k=0;
- uint8_t x=0;
- dst[x] = 0;
- while(*src++){
- if (*src >= '0' && *src <= '9'){
- if (x > len-1){
- memset(dst, 0, len*sizeof(uint8_t));
- return 0;
- }
- dst[x] = dst[x]*10 + *src - '0';
- k = 1;
- } else if (k>0){
- x++;
- dst[x] = 0;
- k = 0;
- }
- }
- return x;
- }
- void rainbow_step(void) {
- //Fade from blue to red
- if(pwm_setting[2] > 0x00 && pwm_setting[0] == 0xFF && pwm_setting[1] == 0x00) {
- pwm_setting[2]--;
- }
- if(pwm_setting[2] == 0xFF && pwm_setting[0] < 0xFF && pwm_setting[1] == 0x00) {
- pwm_setting[0]++;
- }
- //Fade from green to blue
- if(pwm_setting[1] > 0x00 && pwm_setting[2] == 0xFF && pwm_setting[0] == 0x00) {
- pwm_setting[1]--;
- }
- if(pwm_setting[1] == 0xFF && pwm_setting[2] < 0xFF && pwm_setting[0] == 0x00) {
- pwm_setting[2]++;
- }
- // Fade from red to green
- if(pwm_setting[0] > 0x00 && pwm_setting[1] == 0xFF && pwm_setting[2] == 0x00) {
- pwm_setting[0]--;
- }
- if(pwm_setting[0] == 0xFF && pwm_setting[1] < 0xFF && pwm_setting[2] == 0x00) {
- pwm_setting[1]++;
- }
- }
- // 22ms timer
- void timer0_init(void){
- TCCR0 = (1 << CS00)|(1 << CS02); // Prescaler 1024
- TIMSK |= (1 << TOIE0); // Enable timer for TIMER0_OVF_vect mode.
- }
- void rgbw_pwm_init(uint8_t r, uint8_t g, uint8_t b, uint8_t w){
- pwm_setting[0] = r;
- pwm_setting[1] = g;
- pwm_setting[2] = b;
- pwm_setting[3] = w;
- TCCR2 |= (1 << WGM21)|(1 << WGM20)|(1 << CS20);
- TIMSK |= (1 << TOIE2);
- }
- // https://www.forbot.pl/forum/topics33/pwm-tryby-pracy-timera1-w-atmega-8-vt4640.htm
- // http://www.societyofrobots.com/member_tutorials/files/ATMega8.pdf
- // it`s timer_1
- void fan_pwm_init(void){
- // 16 bit Fast PWM
- TCCR1A |= (1<<WGM11);
- //TCCR1B |= (1<<WGM12);// Comment out to have Phase correct instead Fast PWM
- TCCR1B |= (1<<WGM13);
- // Prescaler set to 1.
- TCCR1B |= (1<<CS10);
- // 12 MHz / (prescaler * (TOP + 1)) = 25 kHz
- // 12000000/(1*(479+1)) == 25000Hz
- // Set frequency to 25KHz.
- ICR1 = 479;
- // Set duty cycles.
- //OCR1A = 448;
- OCR1A = 428;
- // Enable output on OC1A
- TCCR1A |= (1<<COM1A1);
- }
- void check_temp(void){
- static int16_t dst=0;
- ds18b20_request_measure();
- int16_t temp = ds18b20_get_temperature(ds_devices[0]);
- if (temp == 2000) return;
- temp /= 10;
- if (dst != temp){
- dst = temp;
- printf("ORG temp %d -> %d\n", temp, (ICR1-(temp-30)*6));
- temp = ICR1-(temp-30)*6;
- if (temp > ICR1) temp=ICR1;
- OCR1A = temp;
- printf("OCR1A IS: %d and temp %d\n", temp, dst);
- }
- }
- // timer ~22ms
- ISR(TIMER0_OVF_vect){
- static volatile uint8_t overflows=0;
- if (overflows++ > 200){
- overflows = 0;
- ready_to_get_temp=1;
- }
- }
- void delay_ms(uint8_t ms){
- while(--ms){
- _delay_ms(1);
- }
- }
- int __attribute__((noreturn)) main(void){
- PRINTF_TO_UART;
- uint8_t rainbow_on = 1;
- uint16_t rainbow_speed = 5;
- uint16_t fan_speed = 2;
- GPIO_OUTPUT(LED_R);
- GPIO_OUTPUT(LED_G);
- GPIO_OUTPUT(LED_B);
- GPIO_OUTPUT(LED_W);
- GPIO_OUTPUT(FAN);
- uart_init();
- timer0_init();
- rgbw_pwm_init(0xFF, 0, 0, 0);
- fan_pwm_init();
- ds18b20_init(DS18B20_RESOLUTION_9_BITS);
- wdt_enable(WDTO_2S);
- sei();
- while(1){
- wdt_reset();
- char *uart_rx_ptr = get_uart_rx();
- if (uart_rx_ptr != NULL){
- if (streq(uart_rx_ptr, "avr ping")){
- printf("avr-pong\r\n");
- } else if (streq(uart_rx_ptr, "avr rgbw")){
- //atoia(uart_rx_ptr, (uint8_t *)pwm_setting, 4);
- uint8_t i = atoia(uart_rx_ptr, (uint8_t *)pwm_setting, 4);
- if (i==4){
- printf("R: %d, G: %d, B: %d, W:%d\n", pwm_setting[0],pwm_setting[1],pwm_setting[2],pwm_setting[3]);
- }
- } else if (streq(uart_rx_ptr, "avr rainbow on")){
- printf("avr rainbow on accepted.\n");
- rainbow_on = 1;
- } else if (streq(uart_rx_ptr, "avr rainbow off")){
- printf("avr rainbow off accepted.\n");
- rainbow_on = 0;
- } else if (streq(uart_rx_ptr, "avr rainbow speed ")){
- rainbow_speed = atoi(uart_rx_ptr+18);
- printf("RS:%d WT\n", rainbow_speed);
- } else if (streq(uart_rx_ptr, "avr fan speed ")){
- fan_speed = (uint16_t)atoi(uart_rx_ptr+14);
- if (fan_speed >= 0 && fan_speed <= ICR1){
- OCR1A = fan_speed;
- printf("FAN speed set to: %d\n", fan_speed);
- } else {
- printf("FAN speed incorrect: %d\n", fan_speed);
- }
- }
- memset(uart_rx_ptr, 0, 250);
- }
- if (rainbow_on == 1){
- delay_ms(rainbow_speed);
- rainbow_step();
- //
- }
- if (ready_to_get_temp == 1){
- ready_to_get_temp = 0;
- // ATOMIC_BLOCK(ATOMIC_FORCEON){
- check_temp();
- //}
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement